/** @file cmd_interface.cpp */
#include <QCoreApplication>
#include <iostream>
#include <string>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>

#include "cmd_interface.h"
#include "filmbaza.h"
#include "eximport.h"
#include "defines.h"
#include "login.h"

using namespace std;
static filmbaza *fb = NULL;
static film_s *film = NULL;

/**
 * @brief filmbaza_print_film_info drukuje informacje o filmie na ekran
 * @param info wskaźnik do struktury informacji o filmie
 */
void filmbaza_print_film_info(struct film_s *info)
{
	const char PRINT_SEPARATOR = '\t';
	std::cout  << info->id << PRINT_SEPARATOR
		<< info->name << PRINT_SEPARATOR
		<< info->rate << PRINT_SEPARATOR
		<< ( info->share.shared ? "yes" : "no" ) << PRINT_SEPARATOR
		<< info->share.name << PRINT_SEPARATOR << std::endl;
}
/**
 * @brief filmbaza_print drukuje baze danych na ekran
 */
void filmbaza_print()
{
    struct film_s **head;
	struct film_s *info;
	
	if ( !fb ) return;
	head = &fb->filmy;
	
	std::cout << "id\t         name       \trate\tshared?\tshared.name\t\n";
	
    list_for_each(info, head) {
		filmbaza_print_film_info(info);
	}
}
/**
 * @brief interfejs tworzenie nowej bazy danych
 */
void cmd_base_new()
{
	string name;
	cout << "Podaj nazwe bazy danych \n";
	cin >> name;
	
	if ( fb ) {
		cout << "Baza danych już istenieje \n";
		return;
	}
	
	fb = filmbaza_create(name);
	if ( !fb ) {
		PERROR(" Błąd tworzenia nowej bazy. ");
		return;
	}
	
	cout << " Nowa filmoteka o nazwie \"" << name << "\" utworzona.\n";
}
/**
 * @brief interfejs do usuwania bazy filmów
 */
void cmd_base_rm()
{
	film = NULL;
	filmbaza_destroy(fb);
	fb = NULL;
	cout << "filmbaza_destroyed \n";
}
/**
 * @brief interfejs importowania bazy filmóœ
 */
void cmd_import_base()
{
	string fn;
	int ret;
	
	if ( !fb ) {
		fb = filmbaza_create("");
		if ( !fb ) {
			cout << " Błąd tworzenia nowej bazy. " << endl;
			fprintf(stderr, " errno %d , strerror: %s \n", errno, strerror(errno) );
			return;
		}
	}
	
	cout << " Podaj nazwe pliku.\n";
	getline(cin, fn);
	
	ret = filmbaza_import(fb, fn);
	if ( ret ) {
		cout << " importowanie nie udało się \n";
		PERROR(" %d ", ret);
	} else {
		cout << "Zaimportowano filmy z pliku " << fn << ".\n";
	}
}
/**
 * @brief interfejs exportowania bazy filmów
 */
void cmd_export_base()
{
	string fn;
	int ret;
	
	cout << " Podaj nazwe pliku." << endl;
	getline(cin, fn);
	
	ret = filmbaza_export(fb, fn);
	if ( ret ) {
		cout << " ekxportowanie nie udało się \n";
	} else {
		cout << "Wyeksportowano filmy do pliku " << fn << ".\n";
	}
}
/**
 * @brief interfejs dodawania nowego filmu
 */
void cmd_film_new()
{
	string name;
	
	cout << "Podaj nazwe nowego filmu.\n";
	getline(cin, name);
	
	if ( filmbaza_add(fb, name) ) {
		cout << "Błąd dodawania nowego filmu \n";
	} else {
		cout << "Dodano nowy film o nazwie " << name << endl;
	}
}
/**
 * @brief interfejs usuwania filmu
 */
void cmd_film_rm()
{
	int id;
	
	cout << "Podaj id filmu do usunięcia\n";
	cin >> id;
	
	filmbaza_delete(fb, id);
	cout << "Usunięto film\n";
}
/**
 * @brief interfejs do wybierania filmu do edycji
 */
struct film_s *cmd_film_choose()
{
	char c;
	int id;
	string st;
	struct film_s *film = NULL;
	
once_again:
	
	cout << "Wciśnij: \n"
		" i - by wybrać film na podstawie id\n"
		" n - by wybrać film na podstawie nazwy\n"
		" q - wróc \n";
	
	cin >> c;
	cin.ignore(1, '\n');
	
	cout << "Podaj id filmu.\n";
	if ( !(cin >> id) ) {
		cout << " Error jakiś wyszedł \n";
		goto once_again;
	}
	cin.ignore(1, '\n');
	film = filmbaza_find_film_id(fb, id);
	cout << "Wybrałeś film: ";
	filmbaza_print_film_info(film);
	
	return film;
}
/**
 * @brief interfejs sortowania filmów
 */
void cmd_sort()
{
	char c;
	int opt;
	
	cout << "Sortuj według: \n"
		" 1 - id\n"
		" 2 - nazwy \n"
		" 3 - oceny\n"
		" 4 - czy jest wypozyczone\n"
		" 5 - kto wypożyczył\n";
	
	cin >> c;
	cin.ignore(1, '\n');
	cin.clear();
	switch(c) {
	case '1':
		opt = FILMBAZA_SORT_ID;
		break;
	case '2':
		opt = FILMBAZA_SORT_NAME;
		break;
	case '3':
		opt = FILMBAZA_SORT_RATE;
		break;
	case '4':
		opt = FILMBAZA_SORT_SHARE_SHARED;
		break;
	case '5':
		opt = FILMBAZA_SORT_SHARE_NAME;
        break;
    default:
        return;
    }
	filmbaza_sort(fb, opt, 1);
}
/**
 * @brief interface tworzy konsolowy interfejs użytkownika
 */
void cmd_interface()
{
	
	cout <<	"FILMOTEKA ver1.1\n";
	
	/* authorization */
	for (;;) {
		string user, pass;
		int ret;
		
		cout << "Podaj nazwe użytkownika:\n";
		cin >> user;
		cout << "Hasło:\n";
		cin >> pass;
		
		ret = uwierzytelnij(user, pass);
        if ( ret == 0 ) {
            cout << "Zalogowano jako użytkownik " << user << "." << endl;
			break;
        } else if ( ret == 1 ) {
            cout << "Zalogowano jako administrator " << user << "." << endl;
            break;
        } else if ( ret < 0 ) {
			 cout << "Złe hasło lub nazwa uzyutkownika" << endl;
		} else {
			cout << "Wystąpił błąd." << endl;
			PERROR("login");
		}
	}
	
	for (;;) {
		char c;
		
		if ( fb ) {
			cout << "Wybrana baza danych: " << fb->name << endl;
			if ( film )
				cout << "Wybrany film do edycji: " << film->name << endl;
		}
		cout << "Wybierz jedną z następujących opcji\n";
		if ( !fb )
			cout << " u - utwórz nową pustą baze danych \n";
		if ( fb )
			cout <<	" r - usuń aktualną baze danych \n"
				" w - wydrukuj baze danych\n";
		cout << " i - importuj baze z pliku\n";
		if ( fb ) {
			cout << " x - exportuj baze do pliku\n"
				" d - dodaj nowy film\n"
				" s - usuń film z bazy\n"
				" h - sortuj filmy\n"
				" v - wybierz film do edycji\n";
			if ( film )
				cout << " c - oceń ten film \n"
					" y - wypożycz ten film znajomemu \n"
					" o - znajomy oddał ten film \n";
		}
		cout << " q - zakończ\n";

		cin.clear();
		cin >> c;
		cin.ignore(1, '\n');
		cin.clear();

		if ( !fb ) {
			switch(c) {
			case 'u':
				cmd_base_new();
			}
		}
		switch(c) {
		case 'i':
			cmd_import_base();
			break;
		case 'q':
			return;
		}
		if ( fb ) {
			switch (c) {
			case 'r':
				cmd_base_rm();
				break;
			case 'w':
				filmbaza_print();
				break;
			case 'x':
				cmd_export_base();
				break;
			case 'd':
				cmd_film_new();
				break;
			case 's':	
				cmd_film_rm();
				break;
			case 'h':
				cmd_sort();
				break;
			case 'v':
				cmd_film_choose();
				break;
			}
			if ( film ) {
				
				switch(c) {
				case 'c':
					{
					int rate;
					cout << " Podaj ocene filmu\n";
					cin >> rate;
					filmbaza_rate(fb, film->id, rate);
					}
					break;
				}
				if ( !film->share.shared ) {
					if ( c == 'y' ) {
						string name;
						cout << "Komu pożyczasz ten film?\n";
						getline(cin, name);
						filmbaza_share(fb, film->id, name);
					} else if ( c == 'o' ) {
						filmbaza_unshare(fb, film->id);
						cout << "Zwrócono film.\n";
					}
				}
			}
		}
	}
		
	if ( fb )
		filmbaza_destroy(fb);
	cout << "Dzieńkuje." << endl;
}

